#include <iostream>
#include <cstring>
#include <cstdio>
#include <sys/types.h>
#include <sys/wait.h>
#include <assert.h>
#include <unistd.h>
using namespace std;

//父进程进行读取，子进程进行写入
int main()
{
    int fds[2];  //用来接受创建管道中的输出型参数
    int d = pipe(fds);
    assert(d==0);
    int id=fork();
    assert(id>=0);

    if(id==0)
    {
        //子进程进行写入，关闭读取
        close(fds[0]);
        //子进程
        int cnt=0;
        const char* s= "这是子进程给父进程发送消息";
        while(true)
        {
            cnt++;
            char buffer[1024];
            //c语言的格式化字符串的输出
            snprintf(buffer,sizeof buffer,"child-->parent: %s[%d][%d]",s,cnt,getpid());
            //将buffer的数据通过系统调用write写到管道中
            write(fds[1],buffer,strlen(buffer));
            if(cnt==5)
                break;
            //sleep(1);
        }
        close(fds[1]);
        exit(0);
    }

    //父进程进行读取，关闭写入
    close(fds[1]);
    while(true)
    {
        char buffer[1024];
        //调用系统调用read从管道文件中读取字符
        ssize_t n= read(fds[0],buffer,sizeof(buffer)-1);
        if(n>0)
        {
            buffer[n]=0;
            cout<<"#"<<buffer<<"| parent pid"<<getpid()<<endl;
        }
        else if(n==0) //当写入操作结束的时候，读取到最后一个字符的时候，可以退出
        {
            cout<<"管道内的内容已经被读取完成"<<endl;
            break;
        }
        
    }
    //父进程，需要等待子进程
    int status=0;
    int n=waitpid(id,&status,0);
    //status的低7位是进程退出码
    cout<<"pid-->"<<(status&0x7F)<<endl;
    assert(n==id);


    //[0]  读相当于一只嘴巴
    //[1]  写 相当于一只钢币
    // cout<<"fds[0]:"<<fds[0]<<endl;
    // cout<<"fds[1]:"<<fds[1]<<endl;
    //std::cout<<"hello c++"<<std::endl;

    return 0;
}
